// 默认计算机存储的数据，展示的数据都是二进制，node采用的buffer开描述二进制数据
// Node中的buffer采用16进制来进行表示 （描述的就是内存）

// i/o：
// 读取文件中的内容放到内存中 -> 写入操作  
// 把内存中的数据读取出来    -> 读取操作

// 内存大小一旦声明后，不能随意更改大小（声明buffer的时候需要指定buffer大小）
// 使用buffer来进行内存的开辟
// 16进制和2进制10进制只是表现形式不同，使用buffer进行内存的存储，其实放入的还是二进制，但我们看到的是十六进制
// 声明buffer方式有三种：
// 1.根据长度声明buffer
// 第一个参数代表新的 Buffer 所需的长度
// console.log(Buffer.alloc(4)) //<Buffer 00 00 00 00>  16进制的每一个字节最大是多少？  每个字节在二进制中最大是11111111，十进制是255，16进制是ff
// console.log(Buffer.alloc(2,255)); //<Buffer ff ff>
// console.log(Buffer.alloc(2,'255')); //<Buffer 32 35>
// 2.用一个数组来声明buffer
// buffer中存放的都是内存空间， arrayBuffer只能由数字组成
// const buf2 = Buffer.from([0x16, '255',1,2,3,4]); // 通过数组来创建buffer可以指定存放的内容 ， 基本用不到
// console.log(buf2); //<Buffer 16 ff 01 02 03 04>
// 3.通过字符串来声明buffer
// console.log(Buffer.from('黄益辉')); //<Buffer e9 bb 84 e7 9b 8a e8 be 89>  node默认采用的编码是utf8，默认不支持gbk
// console.log(Buffer.from('ikki')); //<Buffer 69 6b 6b 69>
// 最小单位是字节 字符串转换成buffer长度可能会变化
// console.log(Buffer.from('25')) //<Buffer 32 35 >
// console.log(Buffer.alloc(3,31)) //<Buffer 31 31 31>

// 计算机的编码 ASCII (一个字符由一个字节来表示 127) 一个字节是255 所以用一个字节就可以表示一个字符
// gb18030 gbk （国标字体） 一个汉字由两个字节组成  255 * 255  gbk 就是最早我们的标识方法 
// unicode组织 -》 utf8 
// buffer.length != 字符串长度

// buffer中常用的方法
// buffer.toString()
// buffer.fill()
// buffer.slice() buffer截取方法，截取的是内存   
// buffer.copy
// buffer.indexOf('x',从哪里开始找)  类似于字符串的indexOf

// Buffer.concat()
// Buffer.isBuffer() 判断是不是buffer

// buffer 常用的操作就是拼接buffer  (分片上传)
// 数据是按照顺序的，可能第一个并没有组成汉字
// let buf4 = Buffer.from('黄益');
// let buf5 = buf4.slice(0, 2); // buffer截取方法
// let buf6 = buf4.slice(2, 6);
// console.log(buf4,buf5+buf6);  //<Buffer e9 bb 84 e7 9b 8a> ��益
// let bigBuffer = Buffer.alloc(6)
// buf5.copy(bigBuffer,0,0,2) // 第一次把两个字节拷贝过去
// buf6.copy(bigBuffer,2,0,4) // 第二次是把4个字节拷贝过去
// console.log(bigBuffer.toString('utf8')); //黄益
// let bigBuffer2 = Buffer.concat([buf5,buf6],9)
// console.log(bigBuffer2); //<Buffer e9 bb 84 e7 9b 8a 00 00 00>
/**
 * copy比较少用
 * @param {*} targetBuffer 目标
 * @param {*} targetStart 目标开始
 * @param {*} sourceStart 源的开始
 * @param {*} sourceEnd 源的结束
 */

Buffer.prototype.copy1 = function(targetBuffer, targetStart, sourceStart = 0, sourceEnd = this.length){
    for (let i = 0; i < sourceEnd-sourceStart; i++) {
        targetBuffer[targetStart+i] = this[sourceStart+i]
    }
}
/**
 * concat常用
 * @param {*} list 拷贝的数组
 * @param {*} len 开辟的内存字节数
 * @returns 
 */
Buffer.concat = function (list, len = list.reduce((a, b) => a + b.length, 0)) {
    let bigBuffer = Buffer.alloc(len);
    let offset = 0;
    for (let i = 0; i < list.length; i++) {
        list[i].copy(bigBuffer, offset);
        offset += list[i].length
    }
    return bigBuffer
}

// buffer.slice() buffer截取方法，截取的是内存  
// 注意点:在开发的时候 重复的更新buffer内容，要考虑之前的内容是否会收到 
// let buffer7 = Buffer.from('123');
// console.log(buffer7[1]); //49
// let newBuffer = buffer7.slice(0, 1); // 截取的是内存空间
// newBuffer[0] = 100; // 改变后 会影响之前内容， 
// console.log(buffer7[0]); //100
// -------- 因为buffer里面装的都是内存---------
let buf = Buffer.alloc(3);
let arr = [];
for (let i = 0; i < 3; i++) {
        buf[i] = i;
        arr.push(buf)
}
console.log(arr); //[ <Buffer 00 01 02>, <Buffer 00 01 02>, <Buffer 00 01 02> ]

let arr1 = [[1], 2, 3];
let newArr = arr1.slice(0, 1); // buffer就类似一个二维数组
newArr[0][0] = 100;
console.log(arr1) //[ [ 100 ], 2, 3 ]

// ----------------------------------------
Buffer.prototype.split = function (sep) { // sep 做分隔符
    // buffer 和字符串的长度不一样
    sep = Buffer.isBuffer(sep) ? sep : Buffer.from(sep);
    let offset = 0; // 不停的修改
    let position = 0; // 找到的位置
    const arr = [];
    while (-1 !== (position = this.indexOf(sep, offset))) {
        arr.push(this.slice(offset,position));
        offset = position + sep.length
    }
    arr.push(this.slice(offset));
    return arr;
}

let buffer10 = Buffer.from('黄益辉');  // 分割buffer  -> 分割成buffer[]
// console.log(buffer10.indexOf('益')); //3
buffer10.split('益').forEach((item)=>{console.log(item.toString()); }) //黄   辉

// buffer的使用  没有数组中filter forEach   buffer 用法很像数组 也很像 字符串 (字符串具备不可变性)




